#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <signal.h>

#include "StdTCP.h"


struct TcpServer
{
    int sock;
};

TcpS *InitTcpServer(const char *ip, short int port)
{
    TcpS* s = (TcpS* )malloc(sizeof(TcpS));
    if(s == NULL)
    {
        printf("InitTcpServer malloc error!\n");
        return NULL ;
    }
    s->sock = socket(AF_INET,SOCK_STREAM,0);
    if(s->sock < 0)
    {
        perror("socket:");
        free(s);
        return NULL;
    }

    int isUse = 1 ;
    
    if( setsockopt(s->sock,SOL_SOCKET,SO_REUSEADDR,&isUse,4)!= 0)
    {
        perror("setsockopt:");
        free(s);
        return NULL;
    }

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = inet_addr(ip);
    if(bind(s->sock,(struct sockaddr*)&addr,sizeof(addr))!= 0)
    {
        perror("bind:");
        free(s);
        return NULL;
    }

    if(listen(s->sock,10) !=  0)
    {
        perror("listen:");
        free(s);
        return NULL ;
    }   


    return s;
}

int TcpServerAccept(TcpS *s)
{
     struct sockaddr_in ClientAddr;
    socklen_t len;
    int  acceptSock = accept(s->sock,(struct sockaddr*)&ClientAddr,&len);

    if(acceptSock < 0 )
    {
        perror("accept:");
        return -1;
    }
    return acceptSock;
}

void TcpServerSend( int ClientSock, void *ptr, size_t size)
{
    if(send(ClientSock,ptr,size,0) < 0 )
        {
            perror("TcpServerSend:");
            return ;
        }
    
}

void TCPServerRecv( int ClientSock, void *ptr, size_t size)
{
    if( recv(ClientSock,ptr,size,0) < 0)
        {
            perror("TcpServerRecv:");
            return ;
        }
}

void ClearTcpServer(TcpS *s)
{
    close(s->sock);
    free(s);
}

struct TcpClient
{
    int sock;
};

TcpC *InitTcpClient(const char *ServerIp, short int ServerPort)
{
    TcpC* c = (TcpC* )malloc(sizeof(TcpC));
    if(c == NULL)
    {
        printf("InitTcpClient malloc error!\n");
        return NULL ;
    }
    c->sock = socket(AF_INET,SOCK_STREAM,0);
    if(c->sock < 0)
    {
        perror("socket:");
        return NULL;
    }

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(ServerPort);
    addr.sin_addr.s_addr = inet_addr(ServerIp);
    if( connect(c->sock,(struct sockaddr*)&addr,sizeof(addr)) != 0 )
    {
        perror(" client connect");
       // return NULL ;
    }
    return c;
}

void TcpClientSend(TcpC *c, void *ptr, size_t size)
{

    if(send(c->sock,ptr,size,0) < 0 )
        {
            perror("TcpClientSend:");
            return ;
        }


}

void TCPClientRecv(TcpC *c, void *ptr, size_t size)
{
    if( recv(c->sock,ptr,size,0) < 0)
        {
            perror("TcpClientRecv:");
            return ;
        }
}

void ClearTcpClient(TcpC *c)
{
    close(c->sock);
    free(c);
}

